﻿package com.petermacko.utils {
	import flash.utils.*;
	
	/**
	 * The Cache class caches objects in memory.
	 * 
	 * @example Caching an object:
	 * <listing>	
	 * var cache:Cache = new Cache();
	 * var toCache:Object = {myKey:"Hello",myOtherKey:"World"};
	 * cache.cacheObject("tocache",toCache);
	 * trace(cache.getCachedObject("tocache"));
	 * </listing>
	 */
	public class Cache
	{
		private var cache:Dictionary; //The memory cache
		private var purgeAllInterval:int; //The interval pointer that is purging all cache.

		public function Cache(purgeAllInterval:int = -1) {
			if(purgeAllInterval > -1) purgeAllInterval = flash.utils.setInterval(purgeAll, purgeAllInterval);
			cache = new Dictionary(true);
		}
		
		//Purges all cache.
		public function purgeAll():void	{
			var k:*;
			for each(k in cache) CacheItem(cache[k]).dispose();
			cache = new Dictionary(true);
		}
		
		//Dispose of this Cache instance.
		public function dispose():void {
			purgeAll();
			cache = null;
		}
		
		//Clear the internal purge all interval.
		public function clearPurgeAllInterval():void {
			clearInterval(purgeAllInterval);
		}
		
		//Set and or reset the purge all interval.
		public function setPurgeAllInterval(interval:Number):void {
			clearInterval(purgeAllInterval);
			setInterval(purgeAll,interval);
		}
		
		//Purge one item.
		public function purgeItem(key:*):void {
			if(!cache[key]) {
				return;
			} else if(cache[key]) {
				var ci:CacheItem = CacheItem(cache[key]);
				ci.dispose();
				cache[key] = null;
			}
		}
		
		/**
		 * Cache an object in memory.
		 * 
		 * @param key The key to store the object by.
		 * @param obj The object data.
		 * @param expiresTimeout The timeout to expire this item after.
		 * @param overwrite	Overwrite the previously cached item.
		 */
		public function cacheObject(key:*, obj:*, expiresTimeout:int = -1, overwrite:Boolean = false):void {
			if(!cache[key] || overwrite) {
				var cacheItem:CacheItem = new CacheItem(key,obj,purgeItem,expiresTimeout);
				cache[key] = cacheItem;
			}
		}
		
		//Test whether or not an object is cached.
		public function isCached(key:*):Boolean	{
			return (!(cache[key]==null));
		}
		
		//Get's a cached Object.
		public function getCachedObject(key:*):* {
			var item:CacheItem = cache[key] as CacheItem;
			return item.object;
		}
	}
}